© 2023 yanghn. All rights reserved. Powered by Obsidian
3.7 softmax 回归简洁实现
要点(基本步骤)
nn.init.normal_(m.weight, std=0.01)
:初始化参数,这里的m
是Sequential
里的模块net = nn.Sequential(nn.Flatten(), nn.Linear(784, 10))
:定义网络,一层展平,一层全连接loss = nn.CrossEntropyLoss(reduction='none')
:交叉熵损失trainer = torch.optim.SGD(net.parameters(), lr=0.1)
:SGD 优化器- 计算损失
1. 初始化模型
导入数据集,保持批的大小为 256
import torch
from torch import nn
from d2l import torch as d2l
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
PyTorch 不会隐式地调整输入的形状,必须先展平。定义网络结构:
该网络有两层,第一次为展平层,注意 Pytorch 中始终第一维为样本个数
# PyTorch不会隐式地调整输入的形状。因此,
# 我们在线性层前定义了展平层(flatten),来调整网络输入的形状
net = nn.Sequential(nn.Flatten(), nn.Linear(784, 10))
def init_weights(m):
if type(m) == nn.Linear:
nn.init.normal_(m.weight, std=0.01) # 下划线结尾的函数都表示原地更新
net.apply(init_weights);
Sequential
定义的对象可以理解为一些模块的容器,apply()
方法对里面的网络层循环调用init_weights
方法
2. 重新审视 Softmax 的实现
回忆 sofmax 函数 :
在数学上这套理论没有问题,但数值上碰到指数额外要注意,如果中的一些数值 inf
(无穷大),最后得到的是0、inf
或 nan
(不是数字)的
对于无穷除以无穷的处理,一个技巧就是同时放缩,都除以一个
这样做避免了
注意
机器学习很多理论上没有问题,但实际实现上会有一些数值问题,例如:
- 碰到
就要考虑上溢问题 - 碰到
就要考虑下溢问题 - 可以利用两者互相抵消
交叉熵损失:信息熵(information entropy)#^62c057
loss = nn.CrossEntropyLoss(reduction='none')
注意
这里 CrossEntropyLoss
已经对输入做了 softmax 运算,所以直接输入神经网络神经元的结果,不需要手动将输出的 y 转化为概率
3. 优化算法
使用学习率为0.1的小批量随机梯度下降作为优化算法
trainer = torch.optim.SGD(net.parameters(), lr=0.1)
4. 训练
num_epochs = 10
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)
d2l.train_ch3
参考:
算法使结果收敛到一个相当高的精度